﻿using System;
using System.Collections.Generic;
using System.Text;
using Pixysoft.Framework.Reflection.Core;
using System.ComponentModel;

namespace Pixysoft.Framework.Reflection
{
    public abstract class DynamicProxy : IDisposable
    {
        DynamicTransparentProxyBase proxy = null;

        protected DynamicProxy(Type interfaceToProxy)
        {
            //type 与 直接使用clone 性能对别：

            //10000次： 142ms ->82ms 接近1倍的性能

            object proxyobj = ReflectionManager.CreateTransparentProxy(interfaceToProxy);

            proxy = proxyobj as DynamicTransparentProxyBase;

            proxy.Initialize(this);
        }

        public object GetTransparentProxy()
        {
            return proxy;
        }

        public abstract IDynamicMethodReturnMessage Invoke(IDynamicMethodCallMessage msg);

        protected IDynamicMethodReturnMessage SyncProcessMessage(IDynamicMethodCallMessage msg)
        {
            IDynamicMethodReturnMessage outmessage = new DynamicMethodReturnMessage(msg.MethodInfo, null,
                Pixysoft.Tools.ParserHelper.GetNullValue(msg.MethodInfo.ReturnType));

            return outmessage;
        }

        protected IDynamicMethodReturnMessage CreateReturnMessage(object returnValue, IDynamicMethodCallMessage msg)
        {
            if (returnValue is Exception)
                return CreateExceptionReturnMessage(returnValue as Exception, msg);

            IDynamicMethodReturnMessage outmessage = new DynamicMethodReturnMessage(msg.MethodInfo, null, returnValue);

            return outmessage;
        }

        protected IDynamicMethodReturnMessage CreateExceptionReturnMessage(Exception ex, IDynamicMethodCallMessage msg)
        {
            IDynamicMethodReturnMessage outmessage = new DynamicMethodReturnMessage(msg.MethodInfo, ex, null);

            return outmessage;
        }

        protected IDynamicMethodReturnMessage CreateVoidReturnMessage(IDynamicMethodCallMessage msg)
        {
            IDynamicMethodReturnMessage outmessage = new DynamicMethodReturnMessage(msg.MethodInfo, null, null);

            return outmessage;
        }

        public virtual void Dispose()
        {
            this.proxy = null;
        }
    }
}
